<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);

namespace app\store\service\meal;

use app\common\enum\order\export\ExportStatus as ExportStatusEnum;
use app\common\library\helper;
use app\common\service\BaseService;
use app\store\model\meal\Menu as OrderModel;
use app\store\model\order\Export as ExportModel;use cores\exception\BaseException;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 * 服务层：订单导出Excel
 * Class Export
 * @package app\store\service\order
 */
class Export extends BaseService
{
    // 表格文件标题名称
    private string $title = '菜品统计';

    /**
     * 执行订单导出excel
     * @param array $param
     * @return bool
     * @throws BaseException
     */
    public function export($date)
    {

        $columns  = ['name', 'num'];
        $columns2 = $this->getColumns($columns);

        // 格式化生成表格数据
        // $excelList = $this->getExcelList($orderList, $columns2);

        // 输出并写入到excel文件
        $filePath = $this->outputExcel($columns2, $date);

        // 新增订单导出记录
        // $this->record($param, $filePath);
        return $filePath;
    }

    /**
     * 根据条件查询订单列表
     * @param array $param
     * @return mixed
     * @throws BaseException
     */
    private function getOrderList($date, $type = 0)
    {
        // 根据条件查询订单列表
        $orderList = (new OrderModel)->getListAll($date, $type);

        return $orderList;
    }

    /**
     * 输出并写入到excel文件
     * @param array $columns 列名
     * @param array $excelList 表格内容
     * @return string
     * @throws BaseException
     */
    private function outputExcel(array $columns, $date): string
    {
        // 生成工作表
        $spreadsheet = new Spreadsheet();
        // 根据条件查询订单列表
        $excelList = $this->getOrderList($date);
        $sheet     = $spreadsheet->getActiveSheet()->setTitle($this->title);
        // 列宽
        $sheet->getDefaultColumnDimension()->setWidth(24);
        // 默认行高
        $sheet->getDefaultRowDimension()->setRowHeight(20);
        // 字体加粗(第一行)
        $sheet->getStyle('1')->getFont()->setBold(true);
        // 写入标题数据
        foreach ($columns as $key => $val) {
            $sheet->setCellValueByColumnAndRow($key + 1, 1, $val);
        }
        // 写入内容数据
        foreach ($excelList as $key => $item) {
            $row = $key + 2;
            foreach (array_values($item) as $k => $val) {
                $sheet->setCellValueByColumnAndRow($k + 1, $row, $val);
            }
        }

        // 根据条件查询订单列表
        $orderList1 = $this->getOrderList($date, 1);

        // 添加第一个工作表并设置数据
        $sheet1 = new Worksheet($spreadsheet, '早餐');
        $spreadsheet->addSheet($sheet1);
        // $sheet1->setCellValue('A1', 'Hello World');
        // $sheet1->setCellValue('B2', 'Welcome to Sheet 1');
        //   $sheet1 = $spreadsheet->getActiveSheet()->setTitle('早餐');
        // 列宽
        $sheet1->getDefaultColumnDimension()->setWidth(24);
        // 默认行高
        $sheet1->getDefaultRowDimension()->setRowHeight(20);
        // 字体加粗(第一行)
        $sheet1->getStyle('1')->getFont()->setBold(true);
        // 写入标题数据
        foreach ($columns as $key => $val) {
            $sheet1->setCellValueByColumnAndRow($key + 1, 1, $val);
        }
        // 写入内容数据
        foreach ($orderList1 as $key => $item) {
            $row = $key + 2;
            foreach (array_values($item) as $k => $val) {
                $sheet1->setCellValueByColumnAndRow($k + 1, $row, $val);
            }
        }

        $orderList2 = $this->getOrderList($date, 2);

        // 添加第二个工作表并设置数据
        $sheet2 = new Worksheet($spreadsheet, '午餐');
        $spreadsheet->addSheet($sheet2);
        // $sheet1->setCellValue('A1', 'Hello World');
        // $sheet1->setCellValue('B2', 'Welcome to Sheet 1');
        // $sheet2 = $spreadsheet->getActiveSheet()->setTitle('午餐');
        // 列宽
        $sheet2->getDefaultColumnDimension()->setWidth(24);
        // 默认行高
        $sheet2->getDefaultRowDimension()->setRowHeight(20);
        // 字体加粗(第一行)
        $sheet2->getStyle('1')->getFont()->setBold(true);
        // 写入标题数据
        foreach ($columns as $key => $val) {
            $sheet2->setCellValueByColumnAndRow($key + 1, 1, $val);
        }
        // 写入内容数据
        foreach ($orderList2 as $key => $item) {
            $row = $key + 2;
            foreach (array_values($item) as $k => $val) {
                $sheet2->setCellValueByColumnAndRow($k + 1, $row, $val);
            }
        }

        $orderList3 = $this->getOrderList($date, 3);

        // 添加第二个工作表并设置数据
        $sheet3 = new Worksheet($spreadsheet, '晚餐');
        $spreadsheet->addSheet($sheet3);
        // $sheet3->setCellValue('A1', 'Hello World');
        // $sheet3->setCellValue('B2', 'Welcome to Sheet 1');
        // $sheet2 = $spreadsheet->getActiveSheet()->setTitle('午餐');
        // 列宽
        $sheet3->getDefaultColumnDimension()->setWidth(24);
        // 默认行高
        $sheet3->getDefaultRowDimension()->setRowHeight(20);
        // 字体加粗(第一行)
        $sheet3->getStyle('1')->getFont()->setBold(true);
        // 写入标题数据
        foreach ($columns as $key => $val) {
            $sheet3->setCellValueByColumnAndRow($key + 1, 1, $val);
        }
        // 写入内容数据
        foreach ($orderList3 as $key => $item) {
            $row = $key + 2;
            foreach (array_values($item) as $k => $val) {
                $sheet3->setCellValueByColumnAndRow($k + 1, $row, $val);
            }
        }

// // 获取当前活动的工作表
        //         $sheet1 = $spreadsheet->getActiveSheet();

// // 设置工作表的标题
        //         $sheet1->setTitle('Sheet 1');

// // 在工作表中添加数据
        //         $sheet1->setCellValue('A1', 'Hello');
        //         $sheet1->setCellValue('B1', 'World');

// // 创建第二个工作表
        //         $sheet2 = $spreadsheet->createSheet('Sheet 2');

// // 设置第二个工作表的标题
        //         $sheet2->setTitle('Sheet 2');

// // 在第二个工作表中添加数据
        //         $sheet2->setCellValue('A1', 'Example');
        //         $sheet2->setCellValue('B1', 'Data');

        // 生成文件路径
        $fileName = 'menu-' . time() . '.xlsx';
        // 获取导出的文件夹路径
        $filePath = $this->getExportPath();
        // 保存到文件
        try {
            $writer = new Xlsx($spreadsheet);
            $writer->save(public_path() . $filePath . $fileName);
        } catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
            throwError($e->getMessage());
        }
        return $filePath . $fileName;
    }

    /**
     * 获取导出的文件夹路径
     * @return string
     */
    private function getExportPath(): string
    {
        $filePath = 'downloads/' . $this->getStoreId() . '/';
        ! is_dir($filePath) && mkdir($filePath, 0755, true);
        return $filePath;
    }

    /**
     * 写入订单导出记录
     * @param array $param
     * @param string $filePath
     * @return void
     */
    private function record(array $param, string $filePath): void
    {
        // 生成记录数据
        $data = [
            'file_path' => $filePath,
            'status'    => ExportStatusEnum::COMPLETED,
            'store_id'  => $this->getStoreId(),
        ];
        // 起止时间
        if (! empty($param['betweenTime'])) {
            $times              = between_time($param['betweenTime']);
            $data['start_time'] = $times['start_time'];
            $data['end_time']   = $times['end_time'];
        }
        // 新增记录
        $model = new ExportModel;
        $model->add($data);
    }

    /**
     * 获取导出的记录列名集
     * @param array $onlyFields
     * @return array
     */
    private function getColumns(array $onlyFields): array
    {
        return array_values(helper::pick($this->dictionary(), $onlyFields));
    }

    /**
     * 订单记录字典
     * @return string[]
     */
    private function dictionary(): array
    {
        return [
            'name' => '菜品名称',
            'num'  => '数量',
        ];
    }

    /**
     * 格式化生成表格数据
     * @param array $orderList
     * @param array $onlyFields
     * @return array
     */
    private function getExcelList(array $orderList, array $onlyFields): array
    {

        // 获取订单表格数据
        $excelList = $this->getOrderDataForExcel($orderList);
        // 仅输出用户设置的字段
        $data = [];
        foreach ($excelList as $item) {
            $data[] = helper::pick($item, $onlyFields);
        }
        return $data;
    }

    /**
     * 获取订单列表数据(用于生成Excel)
     * @param $orderList
     * @return array
     */
    private function getOrderDataForExcel($orderList): array
    {

        // 表格内容
        $dataArray = [];
        foreach ($orderList as $order) {

            $dataArray[] = [
                'name' => $order['name'],
                'num'  => (int) $order['num'],
            ];

        }
        return $dataArray;
    }

    /**
     * 格式化支付方式
     * @param string $payMethod
     * @return string
     */
    private function filterPayMethod(string $payMethod): string
    {
        $enum = PaymentMethodEnum::data();
        return isset($enum[$payMethod]) ? $enum[$payMethod]['name'] : '';
    }

   

    /**
     * 表格值过滤
     * @param $value
     * @return string
     */
    private function filterValue($value): string
    {
        return "\t{$value}\t";
    }
}
